import abc
import os
import zipfile


class ClassBytes:

    def __init__(self, content, entry):
        '''

        content 类的字节数组 []byte
        entry :ClassEntry的实例
        '''
        self.content = content
        self.entry: ClassEntry = entry

    def bytes(self):
        return self.content

    def classEntry(self):
        return self.entry


class ClassEntry:
    def __init__(self):
        pass

    def ReadClass(self, className: str) -> ClassBytes:
        pass

    def String(self) -> str:
        pass


class DirEntry(ClassEntry):
    def __init__(self, absDir):
        self.absDir = absDir

    def ReadClass(self, className: str) -> ClassBytes:
        file_path = os.path.join(self.absDir, className)
        if not os.path.exists(file_path):
            msg = "file:{} not found in dir{}".format(className, self.absDir)
            #print(msg)
            return None
        bytes = None
        with open(file=file_path, mode='rb') as f:
            bytes = f.read()
        return ClassBytes(content=bytes, entry=self)

    def String(self) -> str:
        return self.absDir


class ZipEntry(ClassEntry):
    def __init__(self, absDir):
        self.absDir = absDir

    def ReadClass(self, className: str) -> ClassBytes:
        # 打开ZIP文件
        with zipfile.ZipFile(self.absDir, 'r') as zip_ref:
            # 列出ZIP文件中的所有文件
            #zip_ref.printdir()
            # 检查文件是否存在于ZIP包中
            if className in zip_ref.namelist():
                # 读取文件内容
                with zip_ref.open(className) as file:
                    file_content = file.read()
                    return ClassBytes(content=file_content, entry=self)
            else:
                msg = "文件 {} 不存在于ZIP{}包中。".format(className, self.absDir)
                #print(msg)
                return None

    def String(self) -> str:
        return self.absDir


class CompositeEntry(ClassEntry):
    def __init__(self):
        self.entries = []

    def append(self, entry: ClassEntry):
        self.entries.append(entry)

    def ReadClass(self, className: str) -> ClassBytes:
        for entry in self.entries:
            try:
                val = entry.ReadClass(className=className)
                if val is not None:
                    return val
            except Exception as e:
                pass
        msg = "not found file:{} in dir:{}".format(className, self.String())
        #print(msg)
        return None

    def String(self) -> str:
        entries = []
        for entry in self.entries:
            entries.append(entry.String())
        return ",".join(entries)
